package servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.thoughtworks.xstream.XStream;

import conversion.Factory;
import dataobjects.AddMessage;
import dataobjects.DeleteQuery;
import dataobjects.DislikeQuery;
import dataobjects.HistoryQuery;
import dataobjects.IndifferentQuery;
import dataobjects.LikeQuery;
import dataobjects.Message;
import dataobjects.MessageQuery;
import dataobjects.Query;
import dataobjects.ReportQuery;


/**
 * Servlet implementation class Api
 */
public class Api extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public Api() {
        super();
        // TODO Auto-generated constructor stub
    }
 
	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		PrintWriter out = response.getWriter();
		response.setContentType("text/xml");
		XStream xst = new XStream();
		
		String varname = "action";
		
		String varvalue = request.getParameter(varname);
		
		/*action could be:
		 * 
		 * 1: get all messages (first time app launches)
		 * 2: get messages by category ("cat" must be on the query string too)
		 * 3: posting a vote ("msg" needed)
		 */
		
		try {
			
				List<Long> ids = new ArrayList<Long>();
					MessageQuery query = new MessageQuery();
					List<Message> messageList = Factory.getMessages(query);
					List<Message> allMessages = new ArrayList<Message>();
					query.setAlreadyReadMessages(ids);
					while(messageList.size()>0){
						for(Message m : messageList){
							allMessages.add( m );
							ids.add( m.getId());
						}
						messageList = Factory.getMessages(query);
					}
					out.println(xst.toXML(allMessages));
					
						
	      
		} catch (Exception e) {
			// TODO Auto-generated catch block
			out.println(e.getMessage());
		}
		
		
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		XStream xst = new XStream();
		PrintWriter out = response.getWriter();
		response.setContentType("text/xml");
		
		try
		{
			Query obj = (Query) xst.fromXML(request.getReader());
			switch(obj.getType()){
			case Query.MESSAGE_QUERY:
				handleMessageQuery(xst, out, (MessageQuery)obj);				
				break;			
			case Query.ADD_MESSAGE:
				handleMessageAdd(xst, out, (AddMessage) obj);
				break;
			case Query.HISTORY_QUERY:
				handleHistoryQuery(xst, out, (HistoryQuery) obj);
				break;
			case Query.LIKE_QUERY:
				handleLikeQuery(xst, out, (LikeQuery) obj);
				break;
			case Query.DISLIKE_QUERY:
				handleDislikeQuery(xst, out, (DislikeQuery) obj);
				break;
			case Query.INDIFFERENT_QUERY:
				handleIndifferentQuery(xst, out, (IndifferentQuery) obj);
				break;
			case Query.REPORT_QUERY:
				handleReportQuery(xst, out, (ReportQuery) obj);
				break;
			case Query.DELETE_QUERY:
				handleDeleteQuery(xst, out, (DeleteQuery) obj);
			default:
				handleError(xst, response, obj);
				break;
			}
			
						
		}
		catch(Exception exe)
		{
			out.print( exe.getMessage() );
			response.sendError(404, "Exception thrown (" + exe.getMessage()  + ")");
		}
		
					
		
	}

	private void handleDeleteQuery(XStream xst, PrintWriter out, DeleteQuery obj) {
		out.print(xst.toXML(Factory.delete(obj)));
		
	}

	private void handleError(XStream xst, HttpServletResponse out, Query obj) {
			try {
				out.sendError(404, "Not supported Query (" + obj.getClass().getName().toString()  + ")");
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	}

	private void handleReportQuery(XStream xst, PrintWriter out, ReportQuery obj) {
		 out.println(xst.toXML( Factory.reportMessage(obj)));
		
	}

	private void handleDislikeQuery(XStream xst, PrintWriter out,
			DislikeQuery obj) {
		out.println(xst.toXML( Factory.dislikeMessage(obj)));
		
	}

	private void handleLikeQuery(XStream xst, PrintWriter out, LikeQuery obj) {
		out.println(xst.toXML( Factory.likeMessage(obj)));
		
	}
	
	private void handleIndifferentQuery(XStream xst, PrintWriter out, IndifferentQuery obj) {
		out.println(xst.toXML( Factory.indifferentMessage(obj)));
		
	}

	private void handleHistoryQuery(XStream xst, PrintWriter out,
			HistoryQuery obj) {
		out.println(xst.toXML( Factory.getHistory(obj)));
		
	}

	private void handleMessageAdd(XStream xst, PrintWriter out, AddMessage obj) {
		out.println(xst.toXML( Factory.createMessage(obj)));
		
	}

	private void handleMessageQuery(XStream xst, PrintWriter out, MessageQuery obj) {
		out.println(xst.toXML( Factory.getMessages(obj)));
	}

}
